<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>侦听属性的变化</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>{{msg}}</h1>
        数字:<input type="text" v-model="number" /><br/>
        数字:<input type="text" v-model="a.b"><br/>
        数字:<input type="text" v-model="a.c"><br/>
        数字:<input type="text" v-model="a.d.e.f"><br/>
        数字(后期添加监视):<input type="text" v-model="number2"><br/>
    </div>


    <script>
         const vm = new Vue({
                 el : '#app',
                 //Model M
                 data : {
                     msg : '监听属性',
                     number : 0,
                     number2 : 0,
                     //a属性中保存的值是一个对象的内存地址
                     //a = 0x2356
                     a : {
                         b : 0,
                         c : 0,
                         d : {
                             e : {
                                 f : 0
                             }
                         }
                     }
                 },
                watch : {
                     number : {
                         //初始化的时候,调用一次handler方法
                         immediate : true,
                         //这里有一个固定写死的方法,方法名必须叫做:handler
                         //handler方法什么时候被调用呢?当被监视的属性发生变化的时候,handler就会自动调用一次
                         //handler方法上有两个参数:第一个参数newValue,第二个参数是oldValue
                         //newValue是属性值改变之后的新值.
                         //oldValue是属性值改变之前的旧值
                         handler(newValue , oldValue){
                             console.log(newValue , oldValue)
                             //this是当前的vue实例
                             //如果改函数是箭头函数,这个this就是window对象,不建议使用箭头函数
                             console.log(this)
                         }
                     },
                    //无法监视b属性，因为b属性压根不存在
                    b : {
                        immediate: true,
                        handler(newValue, oldValue) {
                            console.log('b')
                        }
                    },
                    'a.b' : {
                        immediate: true,
                        handler(newValue , oldValue){
                            console.log(newValue , oldValue)
                        }
                    },
                    'a.c' : {
                         handler(newValue , oldValue){
                             console.log(newValue , oldValue)
                         }
                    },
                    a : {
                         //启用深度监视，默认是不开启深度监视的
                        //什么时候开启深度监视:当你需要监听一个具有多级结构的属性,并且监视所有的属性,需要启动深度监视
                        //特别需要注意一点
                        //对象和数组的引用问题
                        //对于对象和数组.oldValue和newValue将是同一个引用,因为Vue为了性能不会深度克隆对象
                        //如果你需要真正的旧值副本,需要在变化前手动克隆
                        //【这个世界上就没有完美的事情,得了这个就不能得那个，正常的，所以不再追求不存在的东西】
                         deep : true,
                         handler(newValue){
                             // console.log(oldValue.d.e.f)
                            const oldValue= this.a.d.e
                            console.log(newValue.d.e.f)
                         }
                    }
                }
             })

        //如何后期添加监听?调用Vue相关的Api即可
        //  vm.$watch('number2' , {
        //      immediate : true,
        //      deep : true,
        //      handler(newValue , oldValue){
        //         console.log(newValue , oldValue)
        //      }
        //  })

         //这是后期添加监听的简写形式
         vm.$watch('number2' , function (newValue , oldValue){
             console.log(newValue , oldValue)
         })

    </script>

</body>
</html>